//
// Created by Administrator on 2025/11/7.
//
#include "student/menu.h"

void display_menu() {
    printf("\n============= 食堂菜单 ============\n");
    printf("ID | 菜品名称       | 分类     | 价格(元) | 库存\n");
    printf("---------------------------------------\n");

    const char *sql = "SELECT id, menu_name, menu_category, menu_money, menu_number FROM canteen_menu;";
    sqlite3_stmt *stmt = NULL;
    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);

    if (rc != SQLITE_OK) {
        fprintf(stderr, "查询菜单失败: %s\n", sqlite3_errmsg(db));
        sqlite3_finalize(stmt);
        return;
    }

    // 遍历查询结果并打印
    while (sqlite3_step(stmt) == SQLITE_ROW) {
        printf("%2d | %-15s | %-8s | %-8d | %d\n",
               sqlite3_column_int(stmt, 0),
               (const char*)sqlite3_column_text(stmt, 1),
               (const char*)sqlite3_column_text(stmt, 2) ? (const char*)sqlite3_column_text(stmt, 2) : "无",
               sqlite3_column_int(stmt, 3),
               sqlite3_column_int(stmt, 4));
    }

    sqlite3_finalize(stmt);
    printf("=======================================\n");
}
Menu* find_menu_item_by_id(int id) {
    static Menu menu; // 静态变量，确保返回后内存有效
    memset(&menu, 0, sizeof(Menu)); // 清空结构体

    const char *sql = "SELECT id, menu_name, menu_category, menu_money, menu_number FROM canteen_menu WHERE id = ?";
    sqlite3_stmt *stmt = NULL;
    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);

    if (rc != SQLITE_OK) {
        fprintf(stderr, "查询菜品失败: %s\n", sqlite3_errmsg(db));
        sqlite3_finalize(stmt);
        return NULL;
    }

    // 绑定菜品ID参数
    sqlite3_bind_int(stmt, 1, id);
    rc = sqlite3_step(stmt);

    // 找到菜品，填充结构体
    if (rc == SQLITE_ROW) {
        menu.id = sqlite3_column_int(stmt, 0);
        strncpy(menu.menu_name, (const char*)sqlite3_column_text(stmt, 1), sizeof(menu.menu_name)-1);
        strncpy(menu.menu_category, (const char*)sqlite3_column_text(stmt, 2), sizeof(menu.menu_category)-1);
        menu.menu_money = sqlite3_column_int(stmt, 3);
        menu.menu_number = sqlite3_column_int(stmt, 4);
    } else {
        sqlite3_finalize(stmt);
        return NULL; // 未找到菜品
    }

    sqlite3_finalize(stmt);
    return &menu;
}

//查询菜单
int menu_query(){
    const char * sql = "select * from canteen_menu;";
    sqlite3_stmt * stmt;
    int rc = sqlite3_prepare_v2(db,sql,-1,&stmt,NULL);
    if(rc!=SQLITE_OK){
        fprintf(stderr,"预编译查询出错了:%s\n", sqlite3_errmsg(db));
        return -1;
    }
    //sqlite3_bind_text(stmt,1,name,-1,SQLITE_TRANSIENT);
    printf("编号\t菜名\t种类\t价格\t数量\n");
    while (sqlite3_step(stmt)==SQLITE_ROW){

        int id = sqlite3_column_int(stmt,0);
        char * menu_name = sqlite3_column_text(stmt,1);
        char * menu_category = sqlite3_column_text(stmt,2);
        int money = sqlite3_column_int(stmt,3);
        int number = sqlite3_column_int(stmt,4);
        printf("%d %s %s %d %d\n",id,menu_name,menu_category,money,number);
    }

    sqlite3_finalize(stmt);
    return 0;
}
//添加菜单
int menu_insert( ){
    printf("--- 进入 menu_insert 函数 ---\n");
    if (db == NULL) {
        fprintf(stderr, "错误：数据库连接句柄 db 为 NULL！\n");
        return -1;
    }else{
        printf("连接句柄db成功\n");
    }


    const char *sql = "insert into canteen_menu (menu_name,menu_category,menu_money,menu_number) values (?,?,?,?);";
    sqlite3_stmt *stmt = NULL;
    int rc;
    printf("准备预处理SQL语句: %s\n", sql);
    rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "无法预处理 SQL(错误码: %d)：%s\n", rc,sqlite3_errmsg(db));
        return -1;
    }
    printf("成功");
    Menu *menu = (Menu *)malloc(sizeof(Menu));
    if (menu == NULL) {
        perror("内存分配失败");
        sqlite3_finalize(stmt);
        return -1;
    }

    // --- 修正后的输入逻辑 ---

    // 1. 读取菜品名字
    printf("请输入菜品名字：");
    // %[^\n] 不会跳过前导换行符，所以必须确保缓冲区干净
    // 在调用 scanf 之前，清空缓冲区
//    while (getchar() != '\n');
    scanf(" %49[^\n]", menu->menu_name);
    // 读取后，清空缓冲区中剩余的内容（包括换行符）
//    while (getchar() != '\n');

    // 2. 读取菜品类别
    printf("请输入菜品类别：");
    // 同样，读取前清空缓冲区
    while (getchar() != '\n');
    scanf("%19[^\n]", menu->menu_category);
    // 读取后清空
    while (getchar() != '\n');

    // 3. 读取菜品价格
    printf("请输入菜品价格：");
    while (1) {
        // %d 会自动跳过前导空白字符（包括换行符），所以读取前可以不清空
        if (scanf("%d", &menu->menu_money) == 1) {
            // 读取成功后，必须清空缓冲区
            while (getchar() != '\n');
            break;
        } else {
            // 读取失败（输入的不是数字）
            printf("输入错误，请输入整数价格：");
            // 清空缓冲区中的无效输入
            while (getchar() != '\n');
        }
    }

    // 4. 读取菜品数量
    printf("请输入菜品数量：");
    while (1) {
        if (scanf("%d", &menu->menu_number) == 1) {
            // 读取成功后，清空缓冲区
            while (getchar() != '\n');
            break;
        } else {
            printf("输入错误，请输入整数数量：");
            while (getchar() != '\n');
        }
    }

    // --- 输入逻辑结束 ---

    // ... 后续的绑定、执行、释放逻辑保持不变 ...
    rc = sqlite3_bind_text(stmt, 1, menu->menu_name, -1, SQLITE_TRANSIENT);
    if (rc != SQLITE_OK) { fprintf(stderr, "绑定菜品名失败：%s\n", sqlite3_errmsg(db)); goto error; }
    rc = sqlite3_bind_text(stmt, 2, menu->menu_category, -1, SQLITE_TRANSIENT);
    if (rc != SQLITE_OK) { fprintf(stderr, "绑定菜品类别失败：%s\n", sqlite3_errmsg(db)); goto error; }
    rc = sqlite3_bind_int(stmt, 3, menu->menu_money);
    if (rc != SQLITE_OK) { fprintf(stderr, "绑定菜品价格失败：%s\n", sqlite3_errmsg(db)); goto error; }
    rc = sqlite3_bind_int(stmt, 4, menu->menu_number);
    if (rc != SQLITE_OK) { fprintf(stderr, "绑定菜品数量失败：%s\n", sqlite3_errmsg(db)); goto error; }

    rc = sqlite3_step(stmt);
    if (rc != SQLITE_DONE) {
        fprintf(stderr, "插入失败：%s\n", sqlite3_errmsg(db));
        goto error;
    }

    printf("插入成功\n");
    sqlite3_finalize(stmt);
    free(menu);
    printf("--- 退出 menu_insert 函数 ---\n");
    return 0;

    error:
    sqlite3_finalize(stmt);
    free(menu);
    return -1;
}

//修改数据并更新
int menu_update(sqlite3 *db,const Menu * m){
    printf("开始进行修改！\n");

    // 调试：打印传入的参数
    printf("调试：传入的菜单信息 -> ID: %d, 名称: '%s', 分类: '%s', 价格: %d, 数量: %d\n",
           m->id, m->menu_name, m->menu_category, m->menu_money, m->menu_number);

    if (db == NULL || m == NULL) {
        fprintf(stderr, "update menu : 参数错误，db 或 m 为 NULL\n");
        return -1;
    }
    if (m->id <= 0) {
        fprintf(stderr, "update menu : 菜单 ID 无效（需为正数）\n");
        return -1;
    }
    if (strlen(m->menu_name) > 50 || strlen(m->menu_category) > 50) {
        fprintf(stderr, "update menu : 菜单名或分类超出最大长度（名称≤%d，分类≤%d）\n",
                50, 50);
        return -1;
    }
    if (m->menu_money < 0 || m->menu_number < 0) {
        fprintf(stderr, "update menu : 价格或数量不能为负数\n");
        return -1;
    }

    const char *sql = "update canteen_menu set "
                      "menu_name = ?, "
                      "menu_category = ?, "
                      "menu_money = ?, "
                      "menu_number = ? "
                      "where id = ?;";
    sqlite3_stmt *stmt = NULL;
    int rc;

    printf("调试：准备 SQL 语句...\n");
    rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "update menu : 准备 SQL 失败 : %s\n", sqlite3_errmsg(db));
        return -2;
    }
    printf("调试：SQL 语句准备成功。\n");

    printf("调试：绑定参数...\n");
    sqlite3_bind_text(stmt, 1, m->menu_name, -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(stmt, 2, m->menu_category, -1, SQLITE_TRANSIENT);
    sqlite3_bind_int(stmt, 3, m->menu_money);
    sqlite3_bind_int(stmt, 4, m->menu_number);
    sqlite3_bind_int(stmt, 5, m->id);
    printf("调试：参数绑定成功。\n");

    printf("调试：执行 SQL 语句...\n");
    rc = sqlite3_step(stmt);
    if (rc != SQLITE_DONE) {
        fprintf(stderr, "update menu : 执行失败 : %s\n", sqlite3_errmsg(db));
        sqlite3_finalize(stmt);
        return -2;
    }
    printf("调试：SQL 语句执行成功。\n");

    int changed_rows = sqlite3_changes(db);
    if (changed_rows == 0) {
        printf("update menu : 未找到 ID 为 %d 的菜单，无记录修改\n", m->id);
    } else {
        printf("update menu : 修改成功！影响行数：%d\n", changed_rows);
    }

    sqlite3_finalize(stmt);
    printf("调试：语句句柄已释放。\n");
    return 0;
}


//定义更新菜单的ui界面
void menu_update_ui(sqlite3 *db) {
    printf("--- 进入修改菜品界面 ---\n");

    // 1. 定义一个 Menu 结构体变量来存储用户输入
    Menu menu_to_update;
    memset(&menu_to_update, 0, sizeof(Menu)); // 初始化结构体

    // 2. 获取用户输入
    printf("请输入要修改的菜品ID: ");
    if (scanf("%d", &menu_to_update.id) != 1) {
        printf("ID输入无效！\n");
        while (getchar() != '\n'); // 清空缓冲区
        return; // 直接返回，结束本次修改操作
    }
    while (getchar() != '\n');

    printf("请输入新的菜品名称: ");
    fgets(menu_to_update.menu_name, sizeof(menu_to_update.menu_name), stdin);
    menu_to_update.menu_name[strcspn(menu_to_update.menu_name, "\n")] = '\0'; // 去掉换行符

    printf("请输入新的菜品分类: ");
    fgets(menu_to_update.menu_category, sizeof(menu_to_update.menu_category), stdin);
    menu_to_update.menu_category[strcspn(menu_to_update.menu_category, "\n")] = '\0';

    printf("请输入新的菜品价格: ");
    if (scanf("%d", &menu_to_update.menu_money) != 1) {
        printf("价格输入无效！\n");
        while (getchar() != '\n');
        return;
    }
    while (getchar() != '\n');

    printf("请输入新的菜品数量: ");
    if (scanf("%d", &menu_to_update.menu_number) != 1) {
        printf("数量输入无效！\n");
        while (getchar() != '\n');
        return;
    }
    while (getchar() != '\n');

    // 3. 调用底层数据库函数来执行更新
    int result = menu_update(db, &menu_to_update);

    // 4. 根据返回结果提示用户
    if (result == 0) {
        printf("菜品修改成功！\n");
    } else {
        printf("菜品修改失败，错误码: %d\n", result);
    }

    printf("--- 退出修改菜品界面 ---\n");
}

//菜单的删除
int menu_delete(sqlite3 *db, int menu_id) {
    // 1. 检查参数合法性
    if (db == NULL || menu_id <= 0) {
        fprintf(stderr, "delete menu : 参数错误（db为空或ID无效）\n");
        return -1;
    }

    // 2. 参数化SQL（防注入，仅绑定ID）
    const char *sql = "DELETE FROM canteen_menu WHERE id = ?;";
    sqlite3_stmt *stmt = NULL;
    int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "delete menu : 准备SQL失败 : %s\n", sqlite3_errmsg(db));
        return -2;
    }

    // 3. 绑定ID参数（索引1，整数类型）
    sqlite3_bind_int(stmt, 1, menu_id);

    // 4. 执行删除（DELETE语句执行后返回SQLITE_DONE）
    rc = sqlite3_step(stmt);
    if (rc != SQLITE_DONE) {
        fprintf(stderr, "delete menu : 执行删除失败 : %s\n", sqlite3_errmsg(db));
        sqlite3_finalize(stmt); // 释放句柄
        return -2;
    }

    // 5. 检查删除行数（确认是否真的删除了记录）
    int deleted_rows = sqlite3_changes(db);
    if (deleted_rows == 0) {
        printf("delete menu : 未找到ID为 %d 的菜单，无记录删除\n", menu_id);
    } else {
        printf("delete menu : 删除成功！影响行数：%d\n", deleted_rows);
        // 手动提交事务（确保修改写入磁盘，避免事务未提交导致数据未变更）
        sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL);
    }

    // 6. 释放资源（必须执行，避免内存泄漏）
    sqlite3_finalize(stmt);
    return 0;
}

//菜单删除时的ui界面
void menu_delete_ui(sqlite3 *db) {
    printf("\n--- 进入删除菜品界面 ---\n");
    int menu_id;

    // 1. 获取用户输入的菜单ID（含输入合法性校验）
    printf("请输入要删除的菜单ID（正数）：");
    if (scanf("%d", &menu_id) != 1) {
        printf("输入无效！请输入一个整数ID。\n");
        while (getchar() != '\n'); // 清空输入缓冲区，避免后续循环异常
        return;
    }
    while (getchar() != '\n'); // 清空残留的换行符

    // 2. 调用数据库层函数执行删除
    int result = menu_delete(db, menu_id);

    // 3. 向用户反馈最终结果
    if (result == 0) {
        printf("菜品删除操作已完成！\n");
    } else {
        printf("菜品删除失败，错误码：%d\n", result);
    }

    printf("--- 退出删除菜品界面 ---\n");
}
